package com.woniuxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.controller.form.*;
import com.woniuxy.controller.info.*;
import com.woniuxy.dao.*;
import com.woniuxy.model.*;
import com.woniuxy.service.DefectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.utils.CopyUtil;
import com.woniuxy.utils.MyException;
import com.woniuxy.utils.TimeMethodsutil;
import net.bytebuddy.implementation.bytecode.Throw;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 马世亮
 * @since 2022-02-15
 */
@Service
public class DefectServiceImpl extends ServiceImpl<DefectDao, Defect> implements DefectService {

    @Resource
    private DefectseverityDao defectseverityDao;
    @Resource
    private DefecttypeDao defecttypeDao;
    @Resource
    private DefectpriorityDao defectpriorityDao;
    @Resource
    private UserDao userDao;
    @Resource
    private DefectstateDao defectstateDao;

    @Resource
    private ProjectDao projectDao;

    @Resource
    private FilesDao filesDao;

    @Resource
    private ProjectRoleUserDao projectRoleUserDao;

    @Resource
    private ResponseDao responseDao;

    @Resource
    private ProjectRoleDao projectRoleDao;

    @Resource
    private WorkhoursDao workhoursDao;

    @Override
    public List<ProjectIdAndNameInfo> getDefectProjectNameAndId(Integer uId) {


        List<ProjectIdAndNameInfo> projectIdAndNameInfos = this.baseMapper.selectMyDefectProject(uId);

        return projectIdAndNameInfos;
    }

    @Override
    public DefectAllDateInfo getDefectAllDate() {

        DefectAllDateInfo defectAllDateInfo = new DefectAllDateInfo();
        List<DefectPriorityIdAndNameInfo> defectPriorityIdAndNameInfos = defectpriorityDao.selectIdAndName();
        defectAllDateInfo.setDefectPriorityIdAndNameInfos(defectPriorityIdAndNameInfos);

        List<DefectTypeIdAndNameInfo> defectTypeIdAndNameInfos = defecttypeDao.selectIdAndName();
        defectAllDateInfo.setDefectTypeIdAndNameInfos(defectTypeIdAndNameInfos);

        List<DefectSeverityIdAndNameInfo> defectSeverityIdAndNameInfos = defectseverityDao.selectIdAndName();
        defectAllDateInfo.setDefectSeverityIdAndNameInfos(defectSeverityIdAndNameInfos);

        List<DefectstateNamesInfo> defectstateNamesInfos = defectstateDao.selectInitState();
        defectAllDateInfo.setDefectstateNamesInfos(defectstateNamesInfos);
        return defectAllDateInfo;
    }

    @Transactional
    @Override
    public void addDefect(AddDefectFrom addDefectFrom) {
        ObjectMapper objectMapper=new ObjectMapper();
        UserInfo userInfo = (UserInfo) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        User user = userDao.selectOne(new QueryWrapper<User>().eq("account_id", userInfo.getId()));
        System.out.println(user);

        Defect defect = CopyUtil.copyOne(addDefectFrom, Defect.class);
        defect.setDefectCreatenameId(user.getUId());
        defect.setDefectCreatename(user.getUName());
        String time = TimeMethodsutil.getNowTimeToString();
        defect.setDefectCreattime(time);


        defect.setDefectStateId(addDefectFrom.getDefectStateId());
        defect.setDefectStateName(addDefectFrom.getDefectStateName());
        defect.setDefectCompletionRate("0%");
        defect.setWorkHours(0);
        defect.setDefectDelete(0);

        int insert = this.baseMapper.insert(defect);


        Files files = new Files();
        files.setFilesDescribe(addDefectFrom.getFilesDescribe());
        files.setDefectId(defect.getDefectId());
        files.setFilesCreatename(user.getUName());
        files.setFilesCreatenameId(user.getUId());
        files.setFilesCreatetime(time);
        files.setFilesIsimg(1);
        String usls =null;
        try {
            usls = objectMapper.writeValueAsString(addDefectFrom.getFilesUrl());
        } catch (JsonProcessingException e) {
            try {
                throw new MyException(500,"添加失败");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        files.setFilesUrl(usls);
        filesDao.insert(files);

    }

    @Override
    public List<DefectAndFileInfo> getMyDefect(DefectConditionForm defectConditionForm) {
        List<Defect> defects = null;
        if (defectConditionForm.getDefectCreatStarttime()==null&&defectConditionForm.getDefectStateId()==null&&defectConditionForm.getProjectId()==null) {
            defects = this.baseMapper.selectList(new QueryWrapper<Defect>().eq("defect_createname_id", defectConditionForm.getUid()));


        }else {
            defects = this.baseMapper.getDefectByCondition(defectConditionForm);
        }
        if(defects==null||defects.size()==0){
            return null;
        }
        List<DefectAndFileInfo> defectAndFileInfos = this.getMyDefectAndFileInfo(defects);
        List<Integer> stateIds = defectstateDao.selectInitStateId();
        for (DefectAndFileInfo defectAndFileInfo : defectAndFileInfos) {
            if(stateIds.contains(defectAndFileInfo.getDefectStateId())){
                defectAndFileInfo.setDefectstateSign("新建");
            }
        }

        return defectAndFileInfos;
    }

    @Override
    public void removeDefect(Integer id) {
        this.baseMapper.deleteById(id);

    }

    @Transactional
    @Override
    public void changeDefect(UpdateDefectForm updateDefectForm) {
        ObjectMapper objectMapper=new ObjectMapper();
        Defect defect = CopyUtil.copyOne(updateDefectForm, Defect.class);
        Files files = new Files();
        files.setFilesDescribe(updateDefectForm.getFilesDescribe());
        try {
            String urls = objectMapper.writeValueAsString(updateDefectForm.getImgs());
            files.setFilesUrl(urls);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        this.baseMapper.updateById(defect);
        this.filesDao.update(files,new QueryWrapper<Files>().eq("defect_id",updateDefectForm.getDefectId()));


    }

    @Override
    public List<DefectAndFileInfo> getNewDefectByMyProject(DefectConditionForm defectConditionForm) {
        List<Defect> defects = null;
        List<Integer> stateIds = defectstateDao.selectInitStateId();
        List<Integer> projectIds=projectRoleUserDao.selectMyProject(defectConditionForm.getUid());
        if (defectConditionForm.getDefectCreatStarttime()==null&&defectConditionForm.getDefectStateId()==null&&defectConditionForm.getProjectId()==null) {

            defects=this.baseMapper.selectMyProjectIsNewDefect(projectIds,stateIds);

        }else {
            defects = this.baseMapper.selectDefectByConditionAndNew(defectConditionForm, stateIds,projectIds);

        }
        if(defects==null||defects.size()==0){
            return null;
        }
        List<DefectAndFileInfo> defectAndFileInfos = this.getMyDefectAndFileInfo(defects);
        return defectAndFileInfos;
    }

    @Override
    public List<UserAndRoleInfo> getProjectMan(Integer projectId) {
        List<ProjectRoleUser> projectRoleUsers = projectRoleUserDao.selectList(new QueryWrapper<ProjectRoleUser>().eq("project_id", projectId));
        if(projectRoleUsers==null||projectRoleUsers.size()==0){
            return null;
        }
        List<ProjectRole> projectRoles = projectRoleDao.selectList(new QueryWrapper<ProjectRole>().eq("system_sign", "产品经理"));
        List<Integer> projectRoleIds=new ArrayList<Integer>();
        for (ProjectRole projectRole : projectRoles) {
            projectRoleIds.add(projectRole.getProjectRoleId());
        }
        List<Integer> uids=new ArrayList<Integer>();
        for (ProjectRoleUser projectRoleUser : projectRoleUsers) {
            if (!projectRoleIds.contains(projectRoleUser.getProjectRoleId())) {
                uids.add(projectRoleUser.getUId());
            }
        }
        List<User> users = userDao.selectBatchIds(uids);
        List<UserAndRoleInfo> userAndRoleInfos = CopyUtil.copyList(users, UserAndRoleInfo.class);

        return userAndRoleInfos;
    }

    @Override
    public void choiceMan(ChoiceUserForm choiceUserForm) {
        Defect defect = CopyUtil.copyOne(choiceUserForm, Defect.class);
        String nowTimeToString = TimeMethodsutil.getNowTimeToString();
        defect.setDefectChoiceTime(nowTimeToString);
        defect.setDefectChangetime(TimeMethodsutil.getNowDateToString());
        this.baseMapper.updateById(defect);

    }

    @Override
    public List<DefectAndFileInfo> getNoNewDefectByMyProject(DefectConditionForm defectConditionForm) {

        List<Defect> defects = null;

        List<Integer> projectIds=projectRoleUserDao.selectMyProject(defectConditionForm.getUid());
        if(projectIds==null||projectIds.size()==0){
            return null;
        }
        List<DefectStateIdAndState> defectStateIdAndStates = defectstateDao.selectNoInitState();
        List<Integer> stateids=new ArrayList<Integer>();
        for (DefectStateIdAndState defectStateIdAndState : defectStateIdAndStates) {
            stateids.add(defectStateIdAndState.getDefectstateId());
        }
        defects=this.baseMapper.selectByMyProjectNoNewDefect(projectIds,defectConditionForm,stateids);


        if(defects==null||defects.size()==0){
            return null;
        }
        List<DefectAndFileInfo> defectAndFileInfos = this.getMyDefectAndFileInfo(defects);
        return defectAndFileInfos;
    }

    @Override
    public List<DefectAndFileInfo> getGiveMeDefect(DefectConditionForm defectConditionForm) {
        QueryWrapper<Defect> wrapper = new QueryWrapper<Defect>().eq("defect_choice_id", defectConditionForm.getUid());

        if(defectConditionForm.getProjectId()!=null){
            wrapper.eq("project_id",defectConditionForm.getProjectId());
        }

        if (defectConditionForm.getDefectCreatStarttime()!=null) {
            wrapper.between("defect_creattime",defectConditionForm.getDefectCreatStarttime(),defectConditionForm.getDefectCreatendtime());
        }
        wrapper.eq("defect_choice_id",defectConditionForm.getUid());
        wrapper.orderByDesc("defect_changetime");
        List<Defect> defects = this.baseMapper.selectList(wrapper);

        List<DefectAndFileInfo> myDefectAndFileInfo = getMyDefectAndFileInfo(defects);
        List<DefectstateNamesInfo> defectstateNamesInfos = defectstateDao.selectChoiceStates();
        List<Integer> stateids=new ArrayList<Integer>();
        for (DefectstateNamesInfo defectstateNamesInfo : defectstateNamesInfos) {
            stateids.add(defectstateNamesInfo.getDefectstateId());
        }
        for (DefectAndFileInfo defectAndFileInfo : myDefectAndFileInfo) {
            if(stateids.contains(defectAndFileInfo.getDefectStateId())){
                defectAndFileInfo.setDefectstateSign("分配");
            }
        }
        return myDefectAndFileInfo;
    }

    @Override
    public void isAcceptDefect(AcceptDefectForm acceptDefectForm) {
        Defect defect = CopyUtil.copyOne(acceptDefectForm, Defect.class);
        defect.setDefectChangetime(TimeMethodsutil.getNowDateToString());
        this.baseMapper.updateById(defect);
    }

    @Transactional
    @Override
    public void responseDefect(ResponseDefectForm responseDefectForm) {
        Defect defect = new Defect();
        defect.setDefectId(responseDefectForm.getDefectId());
        defect.setDefectStateId(responseDefectForm.getDefectStateId());
        defect.setDefectStateName(responseDefectForm.getDefectStateName());
        String nowDateToString = TimeMethodsutil.getNowDateToString();
        defect.setDefectChangetime(nowDateToString);
        this.baseMapper.updateById(defect);
        System.out.println(defect);
        Response response = new Response();
        response.setDefectId(responseDefectForm.getDefectId());
        response.setResponseComments(responseDefectForm.getResponseComments());
        response.setResponseCreatetime(nowDateToString);
        responseDao.insert(response);

    }

    //根据缺陷集合获取对应附件信息，打包返回
    public List<DefectAndFileInfo> getMyDefectAndFileInfo(List<Defect> defects){
        ObjectMapper objectMapper=new ObjectMapper();
        List<DefectAndFileInfo> defectAndFileInfos = CopyUtil.copyList(defects, DefectAndFileInfo.class);

        List<Integer> defectIds=new ArrayList<Integer>();

        for (DefectAndFileInfo defectAndFileInfo : defectAndFileInfos) {
            Files file = filesDao.selectOne(new QueryWrapper<Files>().eq("defect_id", defectAndFileInfo.getDefectId()));
            if(file==null){
                return null;
            }
            defectAndFileInfo.setFilesDescribe(file.getFilesDescribe());
            defectAndFileInfo.setFilesId(file.getFilesId());
            defectAndFileInfo.setFilesUrl(file.getFilesUrl());
            try {
                List<String> list = objectMapper.readValue(file.getFilesUrl(), List.class);
                defectAndFileInfo.setImgs(list);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }

        return defectAndFileInfos;
    }

    @Transactional
    @Override
    public void handleDefect(HandleDefectForm handleDefectForm) {
        Defect defect = CopyUtil.copyOne(handleDefectForm, Defect.class);
        String nowDateToString = TimeMethodsutil.getNowDateToString();
        defect.setDefectChangetime(nowDateToString);

        this.baseMapper.updateById(defect);
        Workhours workhours = new Workhours();
        workhours.setDefectId(defect.getDefectId());
        workhours.setWorkhoursCreatename(handleDefectForm.getUname());
        workhours.setWorkhoursCreatenameId(handleDefectForm.getUid());
        workhours.setWorkhoursNum(handleDefectForm.getWorkHours());
        workhours.setWorkhoursRegistertime(TimeMethodsutil.getNowTimeToString());
        workhoursDao.insert(workhours);

    }
}
